#ifndef DATACONTROLLER_H
#define DATACONTROLLER_H

#include <QMutex>

#include "collection.h"
#include "rule.h"

class DataController
{
public:

    DataController();
    static DataController* instance();

    /* The DataController should have sole access to modifying the objects
        that it is in control of, therefore all accessors of the iVars of this
        class should be constant to prevent their modification outside of this
        class
     */
    inline const Collection& getInputOne()      const { return inputOne; }
    inline const Collection& getInputTwo()      const { return inputTwo; }
    inline const Collection& getOutput()        const { return output; }
    inline const QVector<Rule *>& getRuleList() const { return ruleList; }

    /* Methods gathered from throughout the program that perform whatever
        modifications that may need to be performed on the iVars of this class.
        The functions here are not the functions that the system has to "use"
        the data.  These functions are for the manipulation of the data.  This
        is also where the getters for any often used variables can go, as it
        prevents the need for references to be created.
     */
    void setInputOneFuzzyValues(const double &newValue);
    void setInputTwoFuzzyValues(const double &newValue);
    void setFuzzyValue(const Collection *collection, const double &newValue);
    void setOutputFuzzyValues(const double &newValue);

    void setPoint(const Collection *collection, const int &set,
                  const int &point, const double &newPos);

    void setRuleList(const QVector<Rule *>& newRuleList);
    const QString& findRule(const QString& inputOneName,
                            const QString& inputTwoName);

    double getInputOneInputValue()  const;
    double getInputTwoInputValue()  const;

    double getOutputCrispNumber();

    int getRuleListSize() const;


    const QStringList& getInputOneNames() const;
    const QStringList& getInputTwoNames() const;
    const QStringList& getOutputNames() const;

    /* Input/Output functions.  These functions save and load data to and from
        files.  Having them in this class is not only required because of the
        constant modifiers of all getters, but it also forces the
        DataController to handle such drastic changes to the systems data.
     */
    void loadDataFromFile(const QString& fileName);
    void saveDataToFile(const QString& filename) const;

    /* As more flexibility is added more update functions might be needed.*/
    //void updateSetNameLists(); /*extraneous*/


private:

    /* Function for creating lists of all available set's names. */
    void initializeSetNameLists();
    /* Function to set up a random number for the fuzzy number.*/
    void initializeFuzzyInputNumbers();

    static DataController *pInstance;
    static QMutex threadLock;

    Collection inputOne;
    Collection inputTwo;
    Collection output;

    QVector<Rule *> ruleList;

    QStringList inputOneNames;
    QStringList inputTwoNames;
    QStringList outputNames;
};

#endif // DATACONTROLLER_H
